﻿/***************************************************
 * File name: SaleController.cs 
 * Author: Team A
 * Change Log: Please see SVN repository: http://test-project-drew1.googlecode.com/svn/trunk/
 * Date: December 2013
 * Description: See <summary> tab below
 * *************************************************/

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Migrations;

using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebMatrix.WebData;
using WSCeCommerce.Domain;
using WSCeCommerce.Helpers;
using WSCeCommerceWeb.Models;

namespace WSCeCommerceWeb.Controllers
{
    /// <summary>
    /// Controller used to manage sales. (Generated by MS, customized by Team A)
    /// </summary>
    public class SaleController : Controller
    {

        private const string SESSION_SALE_KEY = "Session.Sale";

        // Customization: Renamed to be consistant with naming standards
        private WSCeCommerceDBContext _db = new WSCeCommerceDBContext();

        //
        // GET: /Sale/

        public ActionResult Index()
        {
            return View(_db.Sales.ToList());
        }

        //
        // GET: /Sale/Details/5

        public ActionResult Details(int id = 0)
        {
            Sale sale = _db.Sales.Find(id);
            if (sale == null)
            {
                return HttpNotFound();
            }
            return View(sale);
        }

        //
        // GET: /Sale/Create

        public ActionResult Create()
        {
            return View();
        }

        //POST: /Sale/Checkout
        [HttpPost]
        public ActionResult CheckOut(Sale sale)
        {
            //TODO Verify Credit card info.

            //We use the sales stored in the session because it can not be maliciously altered by the end user.
            Sale sessionSale = (Sale)HttpContext.Session[SESSION_SALE_KEY];


            sessionSale.ShipToAddress = sale.ShipToAddress;
            sessionSale.CardType = sale.CardType;
            sessionSale.CardNumber = sale.CardNumber;
            sessionSale.Date = DateTime.Now;


            //We need to do this first so that Entity Framework can detect the item already exists in the database

            foreach (SaleItem item in sessionSale.SaleItems)
            {
                Item realItem = _db.Items.Find(item.Item.ItemId);

                //Re - add the item from the database so the Entity Framework recognizes it as an already existing item
                if (realItem != null)
                {
                    item.Item = realItem;
                }

            }

            _db.Sales.AddOrUpdate(sessionSale);
            _db.SaveChanges();

            // Clean up the session
            HttpContext.Session[SESSION_SALE_KEY] = null;
            ShoppingCart.GetCart(this).EmptyCart();


            return View("OrderConfirmed", sessionSale);

        }

        //Get: /Sale/CheckOut
        [HttpGet]
        public ActionResult CheckOut()
        {

            //Convert the cart to sale
            ShoppingCart cart = ShoppingCart.GetCart(this.HttpContext);
            Sale sale = CartToSale(cart);

            //Store the Sale object in the session to be processed later.
            // Note: We do not trust the sale object coming back because it could be malisiosly altered.
            HttpContext.Session[SESSION_SALE_KEY] = sale;

            return View(sale);

        }
        //
        // POST: /Sale/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Sale sale)
        {
            if (ModelState.IsValid)
            {
                _db.Sales.Add(sale);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(sale);
        }

        //
        // GET: /Sale/Edit/5

        public ActionResult Edit(int id = 0)
        {
            Sale sale = _db.Sales.Find(id);
            if (sale == null)
            {
                return HttpNotFound();
            }
            return View(sale);
        }

        //
        // POST: /Sale/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Sale sale)
        {
            if (ModelState.IsValid)
            {
                _db.Entry(sale).State = EntityState.Modified;
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(sale);
        }

        //
        // GET: /Sale/Delete/5

        public ActionResult Delete(int id = 0)
        {
            Sale sale = _db.Sales.Find(id);
            if (sale == null)
            {
                return HttpNotFound();
            }
            return View(sale);
        }

        //
        // POST: /Sale/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Sale sale = _db.Sales.Find(id);
            _db.Sales.Remove(sale);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }

        /// <summary>
        /// Temorary method to dummy up shopping cart
        /// </summary>
        private void DummyUpCart()
        {
            ShoppingCart cart = ShoppingCart.GetCart(this.HttpContext);


            List<Item> items = _db.Items.ToList();

            //Add up to 5 items into the card;
            int itemCount = Math.Min(items.Count, 5);
            for (int x = 0; x < itemCount; x++)
            {
                //Add 2 items to cart
                cart.AddToCart(items[x]);
                cart.AddToCart(items[x]);
            }
        }

        private Sale CartToSale(ShoppingCart cart)
        {

            //Create and initialize the sale
            Sale sale = new Sale()
            {
                Date = DateTime.Now,
                SaleItems = cart.GetCartItems().ToList(),
                UserId = WebSecurity.CurrentUserId
            };

            if (sale.SaleItems != null)
            {
                sale.Total = sale.SaleItems.Sum(item => (item.Price * item.Quantity));
            }
            //Default the Sale's address to the user's address
            //This does not work so we'll do it the hard way
            //UserAddress userAddress = _db.UserAddress.First(ua => ua.UserId == sale.UserId);

            int addressId = _db.Database.SqlQuery<int>("Select Address_AddressId from UserAddresses").First();
            sale.ShipToAddress = _db.Address.Find(addressId);

            return sale;
        }
    }
}